/*
 * Alex Rodrigo de Oliveira - 06/30403
 * Rafaela Porto Osório - 06/94011
 */

#include <stdlib.h>
#include <assert.h>
#include "list.h"


/*
 * Lista de processos agendados (global).
 */
List schedule;


/*
 * Lista de processos em execução (global).
 */
List running;


/*
 * Aloca um novo nó dummy; faz begin e end apontarem para ele; coloca o tamanho
 * como zero e retorna o próprio ponteiro.
 */
List *list_new(List *l)
{
	assert(l != NULL);

	l->begin = l->end = calloc(1, sizeof(Node));
	l->len = 0;
	return l;
}


/*
 * Faz free em todos os nós, inclusive no dummy. Pode deixar ter só lixo na
 * lista.
 */
List *list_del(List *l)
{
	assert(l != NULL);

	Node *n;

	while (l->begin != NULL) {
		n = l->begin->next;
		free(l->begin);
		l->begin = n;
	}
	return l;
}


/*
 * Aloca um novo nó; copia o dado e ajusta os ponteiros dele; ajusta o tamanho e
 * os ponteiros da lista.
 */
Node *list_add(List *l, Node *p, const Job *d)
{
	assert(l != NULL);
	assert(p != NULL);
	assert(d != NULL);

	Node *n;

	/* Prepara o novo nó. */
	n = malloc(sizeof(Node));
	n->data = *d;
	n->prev = p->prev;
	n->next = p;

	/* Ajusta a lista para apontar para o novo nó. */
	if (p != l->begin) {		// prev do begin é NULL
		p->prev->next = n;
	} else {
		l->begin = n;
	}
	p->prev = n;
	++(l->len);
	return n;
}


/*
 * Ajusta os ponteiros dos nós next e prev; ajusta o tamanho da lista; faz free
 * no nó e retorna o next.
 */
Node *list_rem(List *l, Node *p)
{
	assert(l != NULL);
	assert(p != NULL);
	assert(p != l->end);

	Node *n = p->next;

	p->next->prev = p->prev;
	if (p != l->begin) {		// prev do begin é NULL
		p->prev->next = p->next;
	} else {
		l->begin = n;
	}
	--(l->len);
	free(p);
	return n;
}
